﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using App_Code.Helpers;
using Rss;

namespace App_Code.SiteParsers
{
    /// <summary>
    /// Summary description for TopDownMeParser
    /// </summary>
    public class TopDownMeParser : BasePluginParser
    {
        private const string DEFAULT_URL = "http://www.topdown.me/";
        protected const string SEARCH_URL = "http://www.topdown.me/search-{0}";
        private const string MOVIES_URL = "http://www.topdown.me/category/2/%D7%A1%D7%A8%D7%98%D7%99%D7%9D";
        private const string SERIES_URL = "http://www.topdown.me/category/3/%D7%A1%D7%93%D7%A8%D7%95%D7%AA";


        public TopDownMeParser()
        {
            this._defaultUrl = DEFAULT_URL;

            this.Name = "topdown.me";
            this.Description = "אתר צפייה ישירה";
            this.Url = DEFAULT_URL;
        }

        #region Implementation of IPluginParser
        public override RssFeed Run(NameValueCollection queryStringParams)
        {
            this.InitMembers(queryStringParams);

            switch (this._pluginMode)
            {
                case PluginMode.IDLE_MODE:
                    return LoadMainCategories();

                case PluginMode.CATEGORIES_MODE:
                    return LoadCategories();

                case PluginMode.MOVIES_MODE:
                    return LoadMovies();

                case PluginMode.NEXT_PAGE_MODE:
                    return LoadMovies();

                case PluginMode.MOVIE_MODE:
                    return this.LoadMovie();

                case PluginMode.SEARCH_MODE:
                    this.Url = string.Format(SEARCH_URL, this.SearchText);
                    return this.LoadMovies();

                default:
                    throw new Exception("Unknown mode");
            }
        }

        public override void RunUntillPage(int pageNumber)
        {
            //for (var i = 1; i <= pageNumber; i++)
            //{
            //    this.Url = string.Format("{0}page/{1}", DEFAULT_URL, i);
            //    this.LoadMovies();
            //}
        }

        //protected override List<string> GetMovieLinks(string pageContent)
        //{
        //    if (TopdownMeExtractor.IsContainVideoLink(pageContent))
        //    {
        //        return TopdownMeExtractor.GetMovieUrls(pageContent);
        //    }

        //    return new List<string>();
        //}

        #endregion

        #region Private Methods
        private RssFeed LoadMainCategories()
        {
            try
            {
                var rssChannel = new RssChannel
                {
                    Title = string.Format("Movies Channel - {0}", DateTime.Now),
                    Description = "Categories List",
                    Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                    Language = "he"
                };

                rssChannel.LastBuildDate = rssChannel.Items.LatestPubDate();

                var movie = new Movie
                {
                    Name = Common.MOVIES_NAME,
                };

                movie.MovieLinks.Add(MOVIES_URL);

                var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.CATEGORIES_MODE);
                foreach (var movieItem in movieItems)
                {
                    rssChannel.Items.Add(movieItem);
                }

                movie = new Movie
                {
                    Name = Common.SERIES_NAME,
                };

                movie.MovieLinks.Add(SERIES_URL);

                movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.CATEGORIES_MODE);
                foreach (var movieItem in movieItems)
                {
                    rssChannel.Items.Add(movieItem);
                }


                var feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        private RssFeed LoadCategories()
        {
            try
            {
                var rssChannel = new RssChannel
                                     {
                                         Title = string.Format("Movies Channel - {0}", DateTime.Now),
                                         Description = "Categories List",
                                         Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                                         Language = "he"
                                     };

                rssChannel.LastBuildDate = rssChannel.Items.LatestPubDate();

                var page = Utils.GetPage(this.Url, Encoding.GetEncoding("windows-1255"));
                CreateCategorySectionItems(page, rssChannel, this.Url.Equals(HttpUtility.UrlDecode(MOVIES_URL)) ? 2 : 3);

                var feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        private void CreateCategorySectionItems(string page, RssChannel rssChannel, int categoryNumber)
        {
            const string sectionRegEx = "<a href=\"http://www.topdown.me/category/{0}.*?</ul>";

            var moviesSectionRegEx = string.Format(sectionRegEx, categoryNumber);
            var moviesSection = Regex.Match(page, moviesSectionRegEx, RegexOptions.Singleline).Value;

            const string linksRegEx = "<a href=\"(.+?)\">(.+?)</a>";
            var linksMatches = Regex.Matches(moviesSection, linksRegEx, RegexOptions.Singleline);
            foreach (Match linkMatch in linksMatches)
            {
                var moviePageLink = linkMatch.Groups[1].Value;
                var moviePageTitle = linkMatch.Groups[2].Value;

                var movie = new Movie
                {
                    Name = moviePageTitle,
                };

                if (!moviePageLink.Contains(DEFAULT_URL))
                {
                    moviePageLink = moviePageLink.Replace("../", DEFAULT_URL);
                }
                movie.MovieLinks.Add(moviePageLink);

                var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.MOVIES_MODE);
                foreach (var movieItem in movieItems)
                {
                    rssChannel.Items.Add(movieItem);
                }
            }
        }

        private RssFeed LoadMovies()
        {
            try
            {
                var feed = LoadFromCache(this.Url);
                if (feed != null) return feed;

                var page = Utils.GetPage(this.Url, Encoding.GetEncoding("windows-1255"));

                var rssChannel = new RssChannel
                                     {
                                         Title = "Movies Channel",
                                         Description = "Movies List",
                                         Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                                         Language = "he"
                                     };

                rssChannel.LastBuildDate = rssChannel.Items.LatestPubDate();

                //if(this.Url.Equals(HttpUtility.UrlDecode(MOVIES_URL)))
                const string moviesContainerExpression = "<table width=\"540\" style=\"color:#ffffff\" cellpadding=\"0\" cellspacing=\"0\">.*?<td rowspan=\"2\"><a href=\"(.+?)\"><img src=\"(.+?)\" alt=\"(.+?)\".*?</td>";
                var matches = Regex.Matches(page, moviesContainerExpression, RegexOptions.Singleline);
                foreach (Match match in matches)
                {
                    var imageLink = match.Groups[2].Value;
                    var moviePageLink = DEFAULT_URL + match.Groups[1].Value;
                    var movieTitle = match.Groups[3].Value;

                    var movie = new Movie
                    {
                        Name = movieTitle,
                        ImageLink = imageLink,
                    };

                    movie.MovieLinks.Add(moviePageLink);
                    var pageContent = Utils.GetPage(moviePageLink, Encoding.GetEncoding("windows-1255"));
                    movie.MovieLinks = GetMovieLinks(pageContent);

                    var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.MOVIE_MODE);
                    foreach (var movieItem in movieItems)
                    {
                        rssChannel.Items.Add(movieItem);
                    }
                }

                var nextPageMovie = new Movie
                                        {
                                            Name = "דף הבא",
                                        };

                nextPageMovie.MovieLinks.Add(GetNextPageLink(page));
                var nextPageItems = nextPageMovie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.NEXT_PAGE_MODE);
                rssChannel.Items.Add(nextPageItems[0]);

                feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                AddToCache(this.Url, feed);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        private string GetNextPageLink(string pageContent)
        {
            try
            {
                const string nextPageRegEx = "<strong>עמוד:</strong>.*?<strong>.*?<a href=\"(.*?)\"";
                var match = Regex.Match(pageContent, nextPageRegEx);
                if(match.Success)
                {
                    return DEFAULT_URL + match.Groups[1].Value.Replace("&amp;", "&");
                }
            }
            catch { }

            return this.Url;
        }
        #endregion
    }
}